package zxj.baidu.map.utils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.CaseFormat;

/**
 * Map工具类
 * 
 * @author zhuxuejiang
 *
 */
public class MapUtils {

	private static final Logger LOGGER = LoggerFactory.getLogger(MapUtils.class);

	/**
	 * JSON字符串转换为Map
	 * 
	 * @param jsonStr JSON字符串
	 * @return Map实体
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> jsonString2Map(String jsonStr) throws Exception {
		if (StringUtils.isBlank(jsonStr)) {
			return null;
		}

		ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> map;
		try {
			map = mapper.readValue(jsonStr, Map.class);
		} catch (Exception e) {
			LOGGER.error("Map转Object错误！", e);
			throw e;
		}

		return map;
	}

	/**
	 * 获取JSON字符串中的字段值
	 * 
	 * @param jsonStr   JSON字符串
	 * @param fieldName 字段名
	 * @return 字段值
	 * @throws Exception
	 */
	public static Object getFiledFromJsonString(String jsonStr, String fieldName) throws Exception {
		Map<String, Object> map = jsonString2Map(jsonStr);

		if (null == map) {
			return null;
		}

		return map.get(fieldName);
	}

	/**
	 * Map转JSON字符串
	 * 
	 * @param map Map实体
	 * @return JSON字符串
	 * @throws IOException
	 */
	public static String map2JsonString(Map<String, Object> map) throws IOException {
		String jsonStr = null;
		try {
			ObjectMapper mapper = new ObjectMapper();
			jsonStr = mapper.writeValueAsString(map);
		} catch (IOException e) {
			LOGGER.error("Map转Object错误！", e);
			throw e;
		}

		return jsonStr;
	}

	/**
	 * Map转Object
	 * 
	 * @param map   Map实体
	 * @param clazz 实体类
	 * @return
	 * @return 转换后的实体
	 * @throws IOException
	 */
	public static <T> T map2Object(Map<String, Object> map, Class<T> clazz) throws IOException {
		T obj = null;
		try {
			ObjectMapper mapper = new ObjectMapper();
			obj = mapper.readValue(mapper.writeValueAsString(map), clazz);
		} catch (IOException e) {
			LOGGER.error("Map转Object错误！", e);
			throw e;
		}

		return obj;
	}

	/**
	 * Object转Map
	 * 
	 * @param obj 实体
	 * @return Map实体
	 * @throws IOException
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Map<String, Object> object2Map(Object obj) throws IOException {
		Map map = null;
		try {
			ObjectMapper mapper = new ObjectMapper();
			map = mapper.readValue(mapper.writeValueAsString(obj), Map.class);
		} catch (IOException e) {
			LOGGER.error("Map转Object错误！", e);
			throw e;
		}

		return map;
	}

	/**
	 * Object转Map,值为null的属性不添加到Map中
	 * 
	 * @param obj 实体
	 * @return Map实体
	 * @throws IOException
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Map<String, Object> object2MapNonNull(Object obj) throws IOException {
		Map map = null;
		try {
			ObjectMapper mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
			map = mapper.readValue(mapper.writeValueAsString(obj), Map.class);
		} catch (IOException e) {
			LOGGER.error("Map转Object错误！", e);
			throw e;
		}

		return map;
	}

	/**
	 * 将Key由小驼峰规则转换为大驼峰规则
	 * 
	 * @param map Map实体
	 */
	public static Map<String, Object> keyLowerCamel2UpperCamel(Map<String, Object> map) {
		Map<String, Object> newMap = new HashMap<>(16);

		for (Map.Entry<String, Object> entry : map.entrySet()) {
			newMap.put(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, entry.getKey()), entry.getValue());
		}

		return newMap;
	}

	/**
	 * 将Key由大驼峰规则转换为小驼峰规则
	 * 
	 * @param map Map实体
	 */
	public static Map<String, Object> keyUpperCamel2LowerCamel(Map<String, Object> map) {
		Map<String, Object> newMap = new HashMap<>(16);

		for (Map.Entry<String, Object> entry : map.entrySet()) {
			newMap.put(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, entry.getKey()), entry.getValue());
		}

		return newMap;
	}

	/**
	 * 将Key由下划线分割规则转换为小驼峰规则
	 * 
	 * @param map Map实体
	 */
	public static Map<String, Object> keyLowerUnderScore2LowerCamel(Map<String, Object> map) {
		Map<String, Object> newMap = new HashMap<>(16);

		for (Map.Entry<String, Object> entry : map.entrySet()) {
			newMap.put(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, entry.getKey()), entry.getValue());
		}

		return newMap;
	}

	/**
	 * 将Key由小驼峰规则转换为下划线分割规则
	 * 
	 * @param map Map实体
	 */
	public static Map<String, Object> keyLowerCamel2LowerUnderScore(Map<String, Object> map) {
		Map<String, Object> newMap = new HashMap<>(16);

		for (Map.Entry<String, Object> entry : map.entrySet()) {
			newMap.put(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey()), entry.getValue());
		}

		return newMap;
	}
}
